home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 2 / BBS in a box - Trilogy II.iso / Files / Hyper / T / TIFFWindow1.1 / bits.c next >
Encoding:
C/C++ Source or Header  |  1993-04-26  |  7.2 KB  |  304 lines  |  [TEXT/KAHL]

  1. /*
  2.  * This software is copyright 1992 by Robert Morris.
  3.  * You may freely redistribute this software as shareware
  4.  * if you do so in the same form as you got it. If you find
  5.  * this software useful, please send $12 to:
  6.  *   Robert Morris
  7.  *   P.O. Box 1044
  8.  *   Harvard Square Station
  9.  *   Cambridge, MA 02238
  10.  *   ecognome@aol.com
  11.  * If you incorporate any of this software in any kind of
  12.  * commercial product, please send $2 per copy distributed
  13.  * to the above address.
  14.  */
  15.  
  16. #include "bits.h"
  17.  
  18. /* table to reverse bits in a byte */
  19. static unsigned char reverse[];
  20.  
  21. #if 0
  22. /*
  23.  * given a byte, return the position of the first 1. low bit is #0.
  24.  * -1 means none.
  25.  */
  26. static signed char first1[];
  27. #endif
  28.  
  29. OSErr
  30. NewBits(struct bits *b, unsigned char *data, long nbits, char bigendian, int writeable)
  31. {
  32.     b->bits = data;
  33.     b->nbits = nbits;
  34.     b->nextbit = 0;
  35.     b->bigendian = bigendian;
  36.     b->cached = 0;
  37.     if(writeable && bigendian == 0)
  38.         return(-1);
  39.     return(0);
  40. }
  41.  
  42. OSErr
  43. FillBitCache(struct bits *b)
  44. {
  45.     long nbytes, bitno;
  46.     long byteno, cache;
  47.     
  48.     if(TellBits(b) < 0 || TellBits(b) >= b->nbits)
  49.         return(-1);
  50.  
  51.     if((b->nextbit & 7) != 0){
  52.         /* user must have called SeekBits(), so cache is no good */
  53.         byteno = b->nextbit >> 3;
  54.         bitno = b->nextbit & 7;
  55.         
  56.         b->cached = 8 - bitno;
  57.         if(b->cached + b->nextbit > b->nbits)
  58.             b->cached = b->nbits - b->nextbit;
  59.         b->nextbit += b->cached;
  60.         
  61.         cache = b->bits[byteno];
  62.         if(b->bigendian)
  63.             cache = reverse[cache];
  64.         cache >>= bitno;
  65.         b->cache = cache << 1;
  66.     } else if(b->cached < 24){
  67.         b->cache &= (1 << (b->cached + 1)) - 1;
  68.     }
  69.     
  70.     /* now b->nextbit is aligned to a byte */
  71.     
  72.     nbytes = ((24 - b->cached) + 7) / 8;
  73.     byteno = b->nextbit >> 3;
  74.     while(--nbytes >= 0){
  75.         cache = b->bits[byteno];
  76.         if(b->bigendian)
  77.             cache = reverse[cache];
  78.         b->cache |= (cache << (b->cached + 1));
  79.         b->cached += 8;
  80.         b->nextbit += 8;
  81.         byteno++;
  82.     }
  83.     
  84.     return(0);
  85. }
  86.  
  87. long
  88. _ReadBit(struct bits *b)
  89. {
  90.     if(FillBitCache(b) < 0)
  91.         return(-1);    
  92.     return(ReadBit(b));
  93. }
  94.  
  95. #if 0
  96. /*
  97.  * Search, starting with the current bit, for a bit with the same value as wanted.
  98.  * Tries to do byte-at-a-time operations; optimized for longish runs of the same
  99.  * value. A return of -1 means it reached end of file without finding the bit.
  100.  * Otherwise it leaves the position one after the desired bit.
  101.  */
  102. OSErr
  103. ScanBits(struct bits *b, long wanted)
  104. {
  105.     unsigned char *p, *endp;
  106.     int nleft, first;
  107.     unsigned char cache;
  108.     
  109.     /* move to a byte boundary */
  110.     nleft = 8 - (TellBits(b) & 7);
  111.     if(nleft > b->nbits - TellBits(b))
  112.         nleft = b->nbits - TellBits(b);
  113.     if(nleft != 8){
  114.         if(nleft == b->cached){
  115.             cache = b->cache >> 1;
  116.             if(wanted == 0)
  117.                 cache = (~cache & ((1 << nleft) - 1));
  118.             first = first1[cache];
  119.             if(first != -1){
  120.                 SeekBits(b, TellBits(b) + first + 1);
  121.                 return(b->nextbit <= b->nbits ? 0 : -1);
  122.             } else {
  123.                 SeekBits(b, TellBits(b) + nleft);
  124.             }
  125.         } else {
  126.             while(--nleft >= 0)
  127.                 if(ReadBit(b) == wanted)
  128.                     return(b->nextbit <= b->nbits ? 0 : -1);
  129.         }
  130.     }
  131.         
  132.     /* now we can examine a byte at a time */
  133.     p = b->bits + (TellBits(b) >> 3);
  134.     endp = b->bits + ((b->nbits + 7) >> 3);
  135.     if(wanted){
  136.         while(p < endp && *p == 0)
  137.             p++;
  138.     } else {
  139.         while(p < endp && *p == 0xff)
  140.             p++;
  141.     }
  142.     
  143.     SeekBits(b, (p - b->bits) * 8);
  144.     
  145.     /* now look inside this final byte */
  146.     nleft = b->nbits - TellBits(b);
  147.     while(--nleft >= 0)
  148.         if(ReadBit(b) == wanted)
  149.             return(0);
  150.             
  151.     return(-1);
  152. }
  153. #endif
  154.  
  155. OSErr
  156. WriteBits(struct bits *b, long value, long n)
  157. {
  158.     long nhere, here, bitno;
  159.     long byteno;
  160.     
  161.     if(n < 0 || n > 32 || b->nextbit + n > b->nbits)
  162.         return(-1);
  163. #if 0
  164.     /* checked in NewBits */
  165.     if(b->bigendian == 0)
  166.         return(-1);
  167. #endif
  168.         
  169.     byteno = b->nextbit >> 3;
  170.     bitno = b->nextbit & 7;
  171.     b->nextbit += n;
  172.     
  173.     while(n > 0){
  174.         /* how many bits can we write to this byte? */
  175.         nhere = 8 - bitno;
  176.         if(nhere > n)
  177.             nhere = n;
  178.             
  179.         here = (value >> (n - nhere)) & ((1 << nhere) - 1);
  180.         
  181.         if(nhere == 8){
  182.             b->bits[byteno] = here;
  183.         } else {
  184.             here <<= (8 - bitno) - nhere;
  185.             b->bits[byteno] = (b->bits[byteno] & (0xff << (8 - bitno)))
  186.                             | here;
  187.         }
  188.             
  189.         n -= nhere;
  190.         bitno += nhere;
  191.         if(bitno >= 8){
  192.             bitno = 0;
  193.             byteno += 1;
  194.         }
  195.     }
  196.     
  197.     return(0);
  198. }
  199.  
  200. /*
  201.  * Write n bits, all of the same value.
  202.  */
  203. OSErr
  204. _WriteBitSpan(struct bits *b, long bit, long n)
  205. {
  206.     long bitno;
  207.     unsigned char *p, *endp;
  208.     long start = b->nextbit;
  209.     
  210.     if(n < 0 || b->nextbit + n > b->nbits)
  211.         return(-1);
  212. #if 0
  213.     /* checked in NewBits */
  214.     if(b->bigendian == 0)
  215.         return(-1);
  216. #endif
  217.     b->nextbit += n;
  218.         
  219.     if(bit)
  220.         bit = 0xff;
  221.         
  222.     p = b->bits + (start >> 3);
  223.         
  224.     /* align to byte boundary */
  225.     bitno = start & 7;
  226.     if(bitno){
  227.         *p = (bit >> bitno) | (*p & (0xff00 >> bitno));
  228.         n -= 8 - bitno;
  229.         if(n <= 0)
  230.             return(0);
  231.         p++;
  232.     }
  233.     
  234.     /* now write whole bytes */
  235.     endp = p + (n >> 3);
  236.     if(bit){
  237.         while(p < endp)
  238.             *p++ = 0xff;
  239.     } else {
  240.         while(p < endp)
  241.             *p++ = 0;
  242.     }
  243.     
  244.     if(n & 7)
  245.         *p = bit;
  246.     
  247.     return(0);
  248. }
  249.  
  250. static unsigned char reverse[] = {
  251. 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 
  252. 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 
  253. 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 
  254. 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
  255. 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 
  256. 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
  257. 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 
  258. 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
  259. 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 
  260. 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
  261. 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 
  262. 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
  263. 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 
  264. 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
  265. 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 
  266. 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
  267. 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 
  268. 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
  269. 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 
  270. 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
  271. 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 
  272. 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
  273. 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 
  274. 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
  275. 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 
  276. 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
  277. 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 
  278. 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
  279. 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 
  280. 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
  281. 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 
  282. 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 
  283. };
  284.  
  285. #if 0
  286. static signed char first1[] = {
  287. -1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  288. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  289. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  290. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  291. 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  292. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  293. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  294. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  295. 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  296. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  297. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  298. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  299. 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  300. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  301. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  302. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  303. };
  304. #endif